-- 僵尸类
local Object = require("app.mode.Object")
local AniHelper = require("app.utils.AnimateHelper")

local Zombie = {}
Zombie.__index = Zombie
setmetatable(Zombie, Object)

-- 常量
Zombie.NORMAL = 0 -- 正常状态
Zombie.NOHEAD = 1 -- 无头状态
Zombie.JUMPING = 2 -- 跳跃中

Zombie.NORMAL_SPEED = 0 -- 正常速度
Zombie.SLOW_DOWN = 1 -- 减速
Zombie.ACCELERATE = 2 -- 加速

Zombie.MOVING = 0 -- 移动中
Zombie.ATTACKING = 1 -- 攻击中
Zombie.DIE = 2 -- 死亡

function Zombie:initView()
    if self:getBodyState() == Zombie.NORMAL then
        self._sprite, self._animate = AniHelper("zombies/" , self:getName())
    else
        self._sprite, self._animate = AniHelper("zombies/" , self:getLostHeadName())
    end
end

function Zombie:exportData()
    local data = Object.exportData(self)
    data.x, data.y = self:getPosition()
    return data
end

-- 执行动画
function Zombie:runAnimate()
    if self._sprite and self._animate then
        -- 先停止之前的动画
        self._sprite:stopAllActions()

        local sprite, animate

        -- 判断动作状态
        if self:getActionState() == Zombie.MOVING then
            -- 判断身体状态
            if self:getBodyState() == Zombie.NORMAL then
                -- 正常移动
                sprite, self._animate = AniHelper("zombies/" , self:getName())
            elseif self:getBodyState() == Zombie.NOHEAD then
                -- 无头移动
                sprite, self._animate = AniHelper("zombies/" , self:getLostHeadName())
            else
                return
            end
            -- 判断速度状态
            local speed
            if self:getSpeedState() == Zombie.NORMAL_SPEED then
                speed = self:getMoveSpeed()
            elseif self:getSpeedState() == Zombie.SLOW_DOWN then
                speed = self:getMoveSpeed() * 0.6
            elseif self:getSpeedState() == Zombie.ACCELERATE then
                speed = self:getMoveSpeed() * 1.2
            else
                return
            end
            -- 播放移动动画
            self._sprite:setSpriteFrame(sprite:getSpriteFrame())
            self._sprite:runAction(cc.Spawn:create(cc.MoveBy:create(960 / speed, cc.p(-960, 0)), self._animate))
        elseif self:getActionState() == Zombie.ATTACKING then
            if self:getBodyState() == Zombie.NORMAL then
                -- 正常攻击
                sprite, self._animate = AniHelper("zombies/" , self:getAttackName())
            elseif self:getBodyState() == Zombie.NOHEAD then
                -- 无头攻击
                sprite, self._animate = AniHelper("zombies/" , self:getLostHeadAttackName())
            else
                return
            end
            -- 播放攻击动画
            self._sprite:setSpriteFrame(sprite:getSpriteFrame())
            self._sprite:runAction(self._animate)
        elseif self:getActionState() == Zombie.DIE then
            -- 播放死亡动画
            sprite, self._animate = AniHelper("zombies/" , self:getDieName(), 0.1, 1)
            self._sprite:setSpriteFrame(sprite:getSpriteFrame())
            self._sprite:runAction(
                cc.Sequence:create(
                    self._animate,
                    cc.CallFunc:create(
                        function(node, data)
                            self:removeSelf()
                        end
                    ),
                    nil
                )
            )
            self:preRemove()
        end
    end
end

-- 被攻击
function Zombie:beAttack(attack, effect)
    -- 记录状态有没有变化
    local b_change = false

    self:setBlood(self:getBlood() - attack)

    if self:getBlood() <= 0 and self:getActionState() ~= Zombie.DIE then
        -- 血量为零则死亡
        self:setActionState(Zombie.DIE)
        b_change = true
    elseif self:getBlood() <= self:getMaxBlood() * 0.2 and self:getBodyState() ~= Zombie.NOHEAD then
        -- 少于两成血掉头
        self:setBodyState(Zombie.NOHEAD)
        -- 添加头颅动画
        local head, animate = AniHelper("zombies/" , self:getHeadName(), 0.1, 1)
        self:getSprite():addChild(head)
        head:setPosition(50, -20)
        if self:getSpeedState() == Zombie.SLOW_DOWN then
            head:setColor(cc.c3b(33, 198, 241))
        end
        head:runAction(
            cc.Sequence:create(
                animate,
                cc.CallFunc:create(
                    function(node, data)
                        node:removeFromParent()
                    end
                ),
                nil
            )
        )
        b_change = true
    end

    effect = effect or Zombie.NORMAL_SPEED

    if self:getSpeedState() ~= effect then
        self:setSpeedState(effect)
        b_change = true
        if effect == Zombie.SLOW_DOWN then
            -- 减速效果
            self:getSprite():setColor(cc.c3b(33, 198, 241))
        end
    end

    -- 如果状态有变化则更新动画
    if b_change then
        self:runAnimate()
    end
end

-- 被死亡
function Zombie:die()
    self:preRemove()
    self:removeSelf()
end

-- 被爆炸
function Zombie:explode()
    self._sprite:stopAllActions()

    local sprite, animate = AniHelper("zombies/" , "boomdie", 0.1, 1)
    self._sprite:setSpriteFrame(sprite:getSpriteFrame())
    self._animate = animate
    self._sprite:runAction(
        cc.Sequence:create(
            self._animate,
            cc.CallFunc:create(
                function(node, data)
                    self:removeSelf()
                end
            ),
            nil
        )
    )

    self:preRemove()
end

-- 攻击植物
function Zombie:attack(p)
    -- 记录状态有没有变化
    local b_change = self:getActionState() ~= Zombie.ATTACKING

    self:setActionState(Zombie.ATTACKING)

    if self._target == nil then
        self._target = p
        p:addTarget(self)
    end

    -- 如果状态有变化则更新动画
    if b_change then
        self:runAnimate()
    end
end

-- 取消攻击
function Zombie:unAttack()
    self._target = nil

    -- 记录状态有没有变化
    local b_change = self:getActionState() ~= Zombie.MOVING

    self:setActionState(Zombie.MOVING)

    -- 如果状态有变化则更新动画
    if b_change then
        self:runAnimate()
    end
end

-- 移除数据
function Zombie:preRemove()
    -- 移除植物目标
    if self._target then
        self._target:removeTarget(self)
    end
    self._target = nil
    -- 从场景移除僵尸
    self._scene:removeZombie(self)
end

-- 界面显示相关
function Zombie:getCenterPosition()
    local x, y = self._sprite:getPosition()
    return x + self._property.offsetX, y + self._property.offsetY
end

function Zombie:getTarget()
    return self._target
end

-- 属性
function Zombie:getAttackName()
    return self._property.attack_name
end

function Zombie:getHeadName()
    return self._property.head_name
end

function Zombie:getLostHeadName()
    return self._property.losthead_name
end

function Zombie:getLostHeadAttackName()
    return self._property.losthead_attack_name
end

function Zombie:getDieName()
    return self._property.die_name
end

function Zombie:getOffset()
    return self._property.offsetX, self._property.offsetY
end

-- 数据
function Zombie:getTrack()
    return self._data.track
end

function Zombie:setTrack(val)
    self._data.track = val
end

function Zombie:getActionState()
    return self._data.action_state
end

function Zombie:setActionState(val)
    self._data.action_state = val
end

function Zombie:getBodyState()
    return self._data.body_state
end

function Zombie:setBodyState(val)
    self._data.body_state = val
end

function Zombie:getSpeedState()
    return self._data.speed_state
end

function Zombie:setSpeedState(val)
    self._data.speed_state = val
end

return Zombie
